﻿using System.Collections.Generic;
using System.Linq;
using EP.Base.BaseService.Manager.Config.Constant;
using EP.Base.BaseService.Manager.Interface.Business;
using EP.Base.BaseService.Manager.Interface.Common;
using EP.Base.BaseService.Manager.Interface.Data;
using EP.Base.BaseService.Manager.Model.Entity;
using Quartz;
using Quartz.Impl.Triggers;

namespace EP.Base.BaseService.Manager.Business.QzJob
{
    /// <summary>
    /// 执行es任务配置数据监控，发现数据变动实时调整计划任务
    /// </summary>
    public class EsTaskConfigMonitorQzJob:IJob
    {
        private static List<EsTaskConfig> _allTask; 
        public void Execute(IJobExecutionContext context)
        {
            var esMaintainTask = (IEsMaintainTask)context.MergedJobDataMap.Get("IEsMaintainTask");
            var serviceSimplifyLog = (IServiceSimplifyLog)context.MergedJobDataMap.Get("IServiceSimplifyLog");
            var log = (ILog)context.MergedJobDataMap.Get("ILog");
            serviceSimplifyLog.ExecSl("taskConfig数据变更监控任务", () =>
            {
               
                var currentTasks = (List<EsTaskConfig>) context.MergedJobDataMap.Get("CurrentTasks");
                if (_allTask == null)
                {
                    _allTask = currentTasks;
                }
                else
                {
                    currentTasks = _allTask;
                }
                var esTaskConfigs = (IEsTaskConfigs)context.MergedJobDataMap.Get("IEsTaskConfigs");
                var newTasks = esTaskConfigs.GetAll();


                //add 
                var addTask = newTasks.Where(n => !currentTasks.Where(cn => cn.Id == n.Id).Any());
                foreach (var esTaskConfig in addTask)
                {
                    AddJob(log, esTaskConfig, esMaintainTask, serviceSimplifyLog, context);
                }
                //delete 
                var deleteTask = currentTasks.Where(n => !newTasks.Where(cn => cn.Id == n.Id).Any());
                foreach (var esTaskConfig in deleteTask)
                {
                    DeleteJob(log, context, esTaskConfig);
                }
                //modify
                var modifytask = newTasks.Where(n => currentTasks.Any(m => m.Id == n.Id && m.Cron != n.Cron));
                foreach (var esTaskConfig in modifytask)
                {
                    log.DebugFormat("任务esTaskConfigId={0}修改定时任务。", esTaskConfig.Id);
                    var triggerName = EsTaskQzConfig.EsTaskTriggerPre + esTaskConfig.Id;
                    var triggerKey = new TriggerKey(triggerName, EsTaskQzConfig.EsTaskTriggerGroup);

                    var trigger= context.Scheduler.GetTrigger(triggerKey);
                    if (trigger != null)
                    {
                        context.Scheduler.RescheduleJob(triggerKey,
                            new CronTriggerImpl(EsTaskQzConfig.EsTaskTriggerPre + esTaskConfig.Id, EsTaskQzConfig.EsTaskTriggerGroup, esTaskConfig.Cron));
                    }

                }
                //重置
                _allTask = newTasks;
            });
            
        }

        private void DeleteJob(ILog log,IJobExecutionContext context, EsTaskConfig esTaskConfig)
        {
            log.DebugFormat("任务esTaskConfigId={0}删除定时任务。", esTaskConfig.Id);
            context.Scheduler.PauseTrigger(new TriggerKey(EsTaskQzConfig.EsTaskTriggerPre + esTaskConfig.Id, EsTaskQzConfig.EsTaskTriggerGroup));//停止触发器

            context.Scheduler.PauseJob(new JobKey(EsTaskQzConfig.EsTaskJobPre + esTaskConfig.Id, EsTaskQzConfig.EsTaskJobGroup));//暂停任务
            context.Scheduler.DeleteJob(new JobKey(EsTaskQzConfig.EsTaskJobPre + esTaskConfig.Id,EsTaskQzConfig.EsTaskJobGroup));//移除任务

            context.Scheduler.UnscheduleJob(new TriggerKey(EsTaskQzConfig.EsTaskTriggerPre + esTaskConfig.Id, EsTaskQzConfig.EsTaskTriggerGroup));//移除触发器
        }

        private void AddJob(ILog log, EsTaskConfig esTaskConfig, IEsMaintainTask esMaintainTask, IServiceSimplifyLog serviceSimplifyLog, IJobExecutionContext context)
        {
            log.DebugFormat("任务esTaskConfigId={0}创建定时任务。", esTaskConfig.Id);
            //创建一个作业
            IJobDetail srcInitJob = JobBuilder.Create<EsMaintainSingleTaskQzJob>()
                .WithIdentity(EsTaskQzConfig.EsTaskJobPre + esTaskConfig.Id, EsTaskQzConfig.EsTaskJobGroup)
                .Build();
            srcInitJob.JobDataMap.Add("IEsMaintainTask", esMaintainTask);
            srcInitJob.JobDataMap.Add("IServiceSimplifyLog", serviceSimplifyLog);
            srcInitJob.JobDataMap.Add("EsTaskConfigId", esTaskConfig.Id);
            //定义触发器
            ITrigger trigger = TriggerBuilder.Create()
                .WithIdentity(EsTaskQzConfig.EsTaskTriggerPre + esTaskConfig.Id, EsTaskQzConfig.EsTaskTriggerGroup)
                .StartNow() //现在开始
                .WithCronSchedule(esTaskConfig.Cron) //cron表达式
                .Build();

            //把作业，触发器加入调度器。
            context.Scheduler.ScheduleJob(srcInitJob, trigger);
        }
    }
}
